<?php
//	[调用检测] 检测其他程序是否能调用该文件 *M* SQLite 类暂时未写
    if (!defined('Mi18n')) {
        exit('Access Denied');
    }

//	[数据库类]
    class MSQLite extends SQLite3
    {
        private static $_instance;
        private $sqliteObj;
        private $dbFile;
        private $password;
        private $debug = false;
        public $queryLog = array('num'=>0, 'sql'=>array());

        // 提示信息
        public $message = array(
            '101' => '连接数据库失败',
            '102' => '执行SQL失败',
            '103' => '获取数据失败',
            '104' => '插入数据失败',
            '105' => '更新数据失败',
            '106' => '删除数据失败',
            '201' => '传入数据不符合要求'
        );

        /**
         * 构造函数
         **/
        private function __construct()
        {
            $this->dbFile = SQLITE_DATABASE_FILE_PATH;
            $this->password = SQLITE_PASSWORD;
            $this->init();
        }

        /**
         * 覆盖__clone()方法,禁止克隆
         **/
        private function __clone()
        {
        }

        /**
         * 析构函数
         **/
        public function __destruct()
        {
            if ($this->debug) {
                echo $this;
            }
        }

        public function __toString()
        {
            $message = "\r\n<!--\r\n";
            $message .= "Query: ".$this->queryLog['num']."\r\n";
            foreach ($this->queryLog['sql'] as $key => $value) {
                $message .= ($key+1).": ".$value."\r\n";
            }
            $message .= "-->";
            return $message;
        }

        /**
         * 返回对象
         **/
        public static function getInstance()
        {
            if (!(self::$_instance instanceof self)) {
                self::$_instance = new self();
            }
            return self::$_instance;
        }

        /**
         * 连接数据库
         * @return null;
         **/
        public function init()
        {
            try {
                if (!file_exists($this->dbFile)) {
                    $errorArr = array(
                'code' => 101,
                'message' => $this->message[101],
            );
                } else {
                    $this->sqliteObj = new SQLite3($this->dbFile);
                }
            } catch (exception $e) {
                throw new exception($errorArr);
            }
        }

        /**
         * 执行sql语句
         * @param string $sql,SQL语句;
         * @return boolean|mysqli_result;
         **/
        public function query($sql)
        {
            try {
                // 检查表名与数据类型
                if (empty($sql)) {
                    $errorArr = array('code'=>201, 'message'=>$this->message[201]);
                    throw new exception($errorArr);
                }
                // 执行查询
                $result = $this->sqliteObj->query($sql);
                $this->queryLog['num'] += 1;
                $this->queryLog['sql'][] = $sql;
                if (!$result) {
                    $errorArr = array(
                    'code' => 102,
                    'message' => $this->message[102],
                    'mysql' => array('errno'=>$this->errno, 'error'=>$this->error, 'sql'=>$sql),
                );
                } else {
                    return $result;
                }
            } catch (exception $e) {
                throw new exception($errorArr);
            }
        }

        /**
         * 返回结果集的条数
         * @param resource $result,查询结果集;
         * @return mixed;
         **/
        public function numRows($result)
        {
            return $result->num_rows;
        }

        /**
         * 获取数据
         * @param string $sql;
         * @param int $isMulti,0单条,1多条;
         * @return array | boolean;
         **/
        public function get($sql, $isMulti=false)
        {
            // 执行查询
            $result = $this->query($sql);
            // 根据返回类型进行数据返回
            $arr = array();
            if (!$isMulti) {
                //单条返回
                $arr = $result->fetchArray(SQLITE3_ASSOC);
            } else {
                if ($result) {
                    //返回多条
                    while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
                        $arr[] = $row;
                    }
                }
            }
            return $arr;
        }

        /**
         * 插入数据
         * @param string $tableName,表名;
         * @param array $dataArr,数据数组;
         * @return boolean;
         **/
        public function insert($tableName, $dataArr)
        {
            // 检查表名与数据类型
            if (empty($tableName) || !is_array($dataArr)) {
                $errorArr = array('code'=>201, 'message'=>$this->message[201]);
                throw new exception($errorArr);
            }

            try {
                // 对数据进行转义防止入侵
                $dataArr = $this->escapeString($dataArr);
                // 组合SQL语句
                $key = $value = '';
                foreach ($dataArr as $dbKey => $dbValue) {
                    if (!$key) {
                        $key .= '`'.$dbKey.'`';
                        $value .= "'".$dbValue."'";
                    } else {
                        $key .= ',`'.$dbKey.'`';
                        $value .= ",'".$dbValue."'";
                    }
                }
                $sql = "INSERT INTO `".$tableName."` (".$key.") VALUES (".$value.")";
                // 执行并返回结果
                return $this->query($sql);
            } catch (exception $e) {
                $errorArr = array('code'=>104, 'message'=>$this->message[104]);
                throw new exception($errorArr);
            }
        }

        /**
         * 返回上次插入的ID
         * @return mixed;
         **/
        public function getInsertId()
        {
            return $this->insert_id;
        }

        /**
         * 替换数据
         * @param string $tableName,表名;
         * @param array $dataArr,数据数组;
         * @return boolean;
         **/
        public function replace($tableName, $dataArr)
        {
            // 检查表名与数据类型
            if (empty($tableName) || !is_array($dataArr)) {
                $errorArr = array('code'=>201, 'message'=>$this->message[201]);
                throw new exception($errorArr);
            }

            try {
                // 对数据进行转义防止入侵
                $dataArr = $this->escapeString($dataArr);
                // 组合SQL语句
                $key = $value = '';
                foreach ($dataArr as $dbKey => $dbValue) {
                    if (!$key) {
                        $key .= '`'.$dbKey.'`';
                        $value .= "'".$dbValue."'";
                    } else {
                        $key .= ',`'.$dbKey.'`';
                        $value .= ",'".$dbValue."'";
                    }
                }
                $sql = "REPLACE INTO `".$tableName."` (".$key.") VALUES (".$value.")";
                // 执行并返回结果
                return $this->query($sql);
            } catch (exception $e) {
                $errorArr = array('code'=>104, 'message'=>$this->message[104]);
                throw new exception($errorArr);
            }
        }

        /**
         * 更新数据
         * @param array $dataArr,需要更新的字段;
         * @param string $where,查询条件;
         * @return array | boolean;
         **/
        public function update($tableName, $dataArr, $where)
        {
            try {
                if (empty($tableName) || !is_array($dataArr)) {
                    $errorArr = array('code'=>201, 'message'=>$this->message[201]);
                    throw new exception($errorArr);
                }
                $dataArr = $this->escapeString($dataArr);
                $data = '';
                foreach ($dataArr as $key => $value) {
                    if (!$data) {
                        $data .= $key."='".$value."'";
                    } else {
                        $data .= ",".$key."='".$value."'";
                    }
                }
                $sql = "UPDATE `".$tableName."` SET ".$data." WHERE 1 ".$where;
                $result = $this->query($sql);
                return $result;
            } catch (exception $e) {
                $errorArr = array('code'=>105, 'message'=>$this->message[105]);
                throw new exception($errorArr, $e->errorArr);
            }
        }

        /**
         * 删除数据
         * @param string $sql;
         * @param int $isMulti,false单条,true多条;
         * @return array | boolean;
         **/
        public function delete($sql)
        {
            try {
                $result = $this->query($sql);
                return $result;
            } catch (exception $e) {
                $errorArr = array('code'=>106, 'message'=>$this->message[106]);
                throw new exception($errorArr, $e->errorArr);
            }
        }

        /**
         * 字符转义
         * @param $str,需要转义的字符串
         * @param boolean $like
         * @return array|mixed|string
         **/
        public static function escapeString($data)
        {
            if (is_array($data)) {
                foreach ($data as $key => $value) {
                    $data[$key] = htmlspecialchars($value, ENT_QUOTES);
                }
                return $data;
            } else {
                $data = htmlspecialchars($data, ENT_QUOTES);
            }
            return $data;
        }

        /**
         * 关闭数据库连接
         * @return boolean
         **/
        public function close()
        {
            return $this->close();
        }
    }
